/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/*
*  \class	TBasicGrid
*  \author 	Jari Saarinen
*  \date 	Fri Jun 09 15:20:24 2006

*  \version: 	0.1  
*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include "TBasicGrid.h"



TBasicGrid::TBasicGrid(){
	this->data = NULL; 
	this->Nx = 0;
	this->Ny = 0;
	this->data_size = 0;
}

/**
* The constructor
* Takes the grid size in x and y directions as input. 
* @param Nx		The grid size in pixels in x direction (width)
* @param Ny		The grid size in pixels in y direction (height)
*/
TBasicGrid::TBasicGrid(unsigned int Nx, unsigned int Ny)
{
	initBasicGrid(Nx,Ny);	
}

/**
* Destructor Frees the data
*/
TBasicGrid::~TBasicGrid()
{
	if(this->data) free(this->data);
	
}

/**
* This function initializes the Class variables.
*/
void TBasicGrid::initBasicGrid(unsigned int Nx, unsigned int Ny){
	this->data_size = Nx * Ny * sizeof(TBasePixel); // The size of data reserved for the grid
	this->data = (TBasePixel *) malloc(this->data_size);
	this->Nx = Nx;
	this->Ny = Ny;	
}

/**
* Get number of grid pixels in x-direction
*/
unsigned int TBasicGrid::getNX(){
	return this->Nx;
}
/**
* Get number of grid pixels in x-direction
*/
unsigned int TBasicGrid::getNY(){
	return this->Ny;
}

/**
* Get the reserved memory size
*/
unsigned int TBasicGrid::getDataSize(){
	return this->data_size;
}

/**
* Get the pixel from grid position x, y
*/
TBasePixel TBasicGrid::getPixel(unsigned int x, unsigned int y){
	TBasePixel P;

	if( x >= this->Nx || y>=this->Ny){
		//fprintf(stderr,"ERROR::TBasicGrid::getPixel: Invalid pixel position (%u,%u)!\n",x,y);
	}
	else{
		P = this->data[y*Nx+x];
	}
	
	return P;
}

/**
* Set the content of a pixel in to the grid position x,y
* The x and y are given in GRID coordinate system (i.e. relative)
* Not in absolute (0,0 is the up left corner in this coordinate system)
*/
int TBasicGrid::setPixel(TBasePixel P, unsigned int x, unsigned int y){
	if( x >= this->Nx || y>=this->Ny){
		//fprintf(stderr,"ERROR::TBasicGrid::setPixel: Invalid pixel position (%d,%d)!\n",x,y);
		return -1;
	}
	else{
		this->data[y*Nx+x]=P;
	}
	return 0;
}



/**
* Copy the data at once 
* @param *P		the pointer to destination. Memory MUST be reserved. 
* @return		the bytes copied  
*/
int TBasicGrid::getPixelData(TBasePixel *P){
	
	memcpy(P,this->data,this->data_size);
	
	return this->data_size;
}

/**
* Copies the given memory to data field. Be careful with the sizes
* @param *P		The input data. Make sure it is correstly sized
* @param size	The size of the input data, just to be sure!
* @return 0, if ok else -1
*/
int TBasicGrid::setPixelData(TBasePixel *P, unsigned int size){
	if(P == NULL){
		fprintf(stderr,"ERROR::TBasicGrid::setPixelData, Input NULL\n");
		return -1;
	}
	if(size != this->data_size){
		fprintf(stderr,"ERROR::TBasicGrid::setPixelData, Invalid input size\n");
		return -1;
	}
	memcpy(this->data, P, size);
	return 0;
}


/**
* Sets the whole data into given value
*/
void TBasicGrid::initPixelData(unsigned char value){
	memset(this->data,(int) value, this->data_size);	
}

/**
* Copies the data byte by byte to textfile with white space between bytes and line feed
* after sizeof(TBasePixel) * Nx
* @param filename the file to save the data
*/
void TBasicGrid::toTextFile(const char *filename){
	FILE *f;
	int i;
	int j;
	char *p;
	p = (char *) this->data;

	f = fopen(filename,"wt");
	for(j=0;j<(int)Ny;j++){
		for(i=0;i<((int)(this->Nx * sizeof(TBasePixel)));i++){
			fprintf(f,"%c ",p[j*Nx* sizeof(TBasePixel)+i]);	
		}
		fprintf(f,"\n");
	}

	fclose(f);
}

/**
* Prints the internal variables to *f
* @param *f the pointer to file stream
*/
void TBasicGrid::printBasicGridInfo(FILE *f){
	fprintf(f,"TBasicGrid:: (Nx: %d, Ny: %d) size %d\n",this->Nx,this->Ny,this->data_size);
}

TBasePixel *TBasicGrid::getDataPtr(){
  return data;
}
